View Javadoc
1 /* 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 2002 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, 20 * if any, must include the following acknowledgment: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.apache.org/)." 23 * Alternately, this acknowledgment may appear in the software itself, 24 * if and wherever such third-party acknowledgments normally appear. 25 * 26 * 4. The names "Apache" and "Apache Software Foundation" must 27 * not be used to endorse or promote products derived from this 28 * software without prior written permission. For written 29 * permission, please contact apache@apache.org. 30 * 31 * 5. Products derived from this software may not be called "Apache", 32 * nor may "Apache" appear in their name, without prior written 33 * permission of the Apache Software Foundation. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.apache.org/>;. 53 */ 54 package net.sf.cglib.core; 55 56 import java.beans.*; 57 import java.lang.reflect.*; 58 import java.util.*; 59 import org.objectweb.asm.Type; 60 61 /*** 62 * @version $Id: ReflectUtils.java,v 1.20 2004/02/11 18:32:35 baliuka Exp $ 63 */ 64 public class ReflectUtils { 65 private ReflectUtils() { } 66 67 private static final Map primitives = new HashMap(8); 68 private static final Map transforms = new HashMap(8); 69 private static final ClassLoader defaultLoader = ReflectUtils.class.getClassLoader(); 70 private static Method DEFINE_CLASS; 71 private static final java.security.ProtectionDomain PROTECTION_DOMAIN; 72 73 static { 74 75 PROTECTION_DOMAIN = (java.security.ProtectionDomain) 76 java.security.AccessController.doPrivileged( 77 new java.security.PrivilegedAction() { 78 public Object run() { 79 return ReflectUtils.class.getProtectionDomain(); 80 } 81 } 82 ); 83 84 java.security.AccessController.doPrivileged( 85 new java.security.PrivilegedAction() { 86 public Object run() { 87 88 try { 89 90 DEFINE_CLASS = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{ String.class ,byte[].class, int.class, int.class,java.security.ProtectionDomain.class }); 91 DEFINE_CLASS.setAccessible(true); 92 93 } catch (NoSuchMethodException e) { 94 throw new CodeGenerationException(e); 95 } 96 return null; 97 } 98 } 99 ); 100 } 101 102 private static final String[] CGLIB_PACKAGES = { 103 "java.lang", 104 }; 105 106 static { 107 primitives.put("byte", Byte.TYPE); 108 primitives.put("char", Character.TYPE); 109 primitives.put("double", Double.TYPE); 110 primitives.put("float", Float.TYPE); 111 primitives.put("int", Integer.TYPE); 112 primitives.put("long", Long.TYPE); 113 primitives.put("short", Short.TYPE); 114 primitives.put("boolean", Boolean.TYPE); 115 116 transforms.put("byte", "B"); 117 transforms.put("char", "C"); 118 transforms.put("double", "D"); 119 transforms.put("float", "F"); 120 transforms.put("int", "I"); 121 transforms.put("long", "J"); 122 transforms.put("short", "S"); 123 transforms.put("boolean", "Z"); 124 } 125 126 public static Type[] getExceptionTypes(Member member) { 127 if (member instanceof Method) { 128 return TypeUtils.getTypes(((Method)member).getExceptionTypes()); 129 } else if (member instanceof Constructor) { 130 return TypeUtils.getTypes(((Constructor)member).getExceptionTypes()); 131 } else { 132 throw new IllegalArgumentException("Cannot get exception types of a field"); 133 } 134 } 135 136 public static Signature getSignature(Member member) { 137 if (member instanceof Method) { 138 return new Signature(member.getName(), Type.getMethodDescriptor((Method)member)); 139 } else if (member instanceof Constructor) { 140 Type[] types = TypeUtils.getTypes(((Constructor)member).getParameterTypes()); 141 return new Signature(Constants.CONSTRUCTOR_NAME, 142 Type.getMethodDescriptor(Type.VOID_TYPE, types)); 143 144 } else { 145 throw new IllegalArgumentException("Cannot get signature of a field"); 146 } 147 } 148 149 public static Constructor findConstructor(String desc) { 150 return findConstructor(desc, defaultLoader); 151 } 152 153 public static Constructor findConstructor(String desc, ClassLoader loader) { 154 try { 155 int lparen = desc.indexOf('('); 156 String className = desc.substring(0, lparen).trim(); 157 return getClass(className, loader).getConstructor(parseTypes(desc, loader)); 158 } catch (ClassNotFoundException e) { 159 throw new CodeGenerationException(e); 160 } catch (NoSuchMethodException e) { 161 throw new CodeGenerationException(e); 162 } 163 } 164 165 public static Method findMethod(String desc) { 166 return findMethod(desc, defaultLoader); 167 } 168 169 public static Method findMethod(String desc, ClassLoader loader) { 170 try { 171 int lparen = desc.indexOf('('); 172 int dot = desc.lastIndexOf('.', lparen); 173 String className = desc.substring(0, dot).trim(); 174 String methodName = desc.substring(dot + 1, lparen).trim(); 175 return getClass(className, loader).getDeclaredMethod(methodName, parseTypes(desc, loader)); 176 } catch (ClassNotFoundException e) { 177 throw new CodeGenerationException(e); 178 } catch (NoSuchMethodException e) { 179 throw new CodeGenerationException(e); 180 } 181 } 182 183 private static Class[] parseTypes(String desc, ClassLoader loader) throws ClassNotFoundException { 184 int lparen = desc.indexOf('('); 185 int rparen = desc.indexOf(')', lparen); 186 List params = new ArrayList(); 187 int start = lparen + 1; 188 for (;;) { 189 int comma = desc.indexOf(',', start); 190 if (comma < 0) { 191 break; 192 } 193 params.add(desc.substring(start, comma).trim()); 194 start = comma + 1; 195 } 196 if (start < rparen) { 197 params.add(desc.substring(start, rparen).trim()); 198 } 199 Class[] types = new Class[params.size()]; 200 for (int i = 0; i < types.length; i++) { 201 types[i] = getClass((String)params.get(i), loader); 202 } 203 return types; 204 } 205 206 private static Class getClass(String className, ClassLoader loader) throws ClassNotFoundException { 207 return getClass(className, loader, CGLIB_PACKAGES); 208 } 209 210 private static Class getClass(String className, ClassLoader loader, String[] packages) throws ClassNotFoundException { 211 String save = className; 212 int dimensions = 0; 213 int index = 0; 214 while ((index = className.indexOf("[]", index) + 1) > 0) { 215 dimensions++; 216 } 217 StringBuffer brackets = new StringBuffer(className.length() - dimensions); 218 for (int i = 0; i < dimensions; i++) { 219 brackets.append('['); 220 } 221 className = className.substring(0, className.length() - 2 * dimensions); 222 223 String prefix = (dimensions > 0) ? brackets + "L" : ""; 224 String suffix = (dimensions > 0) ? ";" : ""; 225 try { 226 return Class.forName(prefix + className + suffix, false, loader); 227 } catch (ClassNotFoundException ignore) { } 228 for (int i = 0; i < packages.length; i++) { 229 try { 230 return Class.forName(prefix + packages[i] + '.' + className + suffix, false, loader); 231 } catch (ClassNotFoundException ignore) { } 232 } 233 if (dimensions == 0) { 234 Class c = (Class)primitives.get(className); 235 if (c != null) { 236 return c; 237 } 238 } else { 239 String transform = (String)transforms.get(className); 240 if (transform != null) { 241 try { 242 return Class.forName(brackets + transform, false, loader); 243 } catch (ClassNotFoundException ignore) { } 244 } 245 } 246 throw new ClassNotFoundException(save); 247 } 248 249 250 public static Object newInstance(Class type) { 251 return newInstance(type, Constants.EMPTY_CLASS_ARRAY, null); 252 } 253 254 public static Object newInstance(Class type, Class[] parameterTypes, Object[] args) { 255 return newInstance(getConstructor(type, parameterTypes), args); 256 } 257 258 public static Object newInstance(final Constructor cstruct, final Object[] args) { 259 260 boolean flag = cstruct.isAccessible(); 261 try { 262 cstruct.setAccessible(true); 263 Object result = cstruct.newInstance(args); 264 return result; 265 } catch (InstantiationException e) { 266 throw new CodeGenerationException(e); 267 } catch (IllegalAccessException e) { 268 throw new CodeGenerationException(e); 269 } catch (InvocationTargetException e) { 270 throw new CodeGenerationException(e.getTargetException()); 271 } finally { 272 cstruct.setAccessible(flag); 273 } 274 275 } 276 277 public static Constructor getConstructor(Class type, Class[] parameterTypes) { 278 try { 279 return type.getConstructor(parameterTypes); 280 } catch (NoSuchMethodException e) { 281 throw new CodeGenerationException(e); 282 } 283 } 284 285 public static Class[] getClasses(Object[] objects) { 286 Class[] classes = new Class[objects.length]; 287 for (int i = 0; i < objects.length; i++) { 288 classes[i] = objects[i].getClass(); 289 } 290 return classes; 291 } 292 293 public static Method findNewInstance(Class iface) { 294 Method m = findInterfaceMethod(iface); 295 if (!m.getName().equals("newInstance")) { 296 throw new IllegalArgumentException(iface + " missing newInstance method"); 297 } 298 return m; 299 } 300 301 public static Method[] getPropertyMethods(PropertyDescriptor[] properties, boolean read, boolean write) { 302 Set methods = new HashSet(); 303 for (int i = 0; i < properties.length; i++) { 304 PropertyDescriptor pd = properties[i]; 305 if (read) { 306 methods.add(pd.getReadMethod()); 307 } 308 if (write) { 309 methods.add(pd.getWriteMethod()); 310 } 311 } 312 methods.remove(null); 313 return (Method[])methods.toArray(new Method[methods.size()]); 314 } 315 316 public static PropertyDescriptor[] getBeanProperties(Class type) { 317 return getPropertiesHelper(type, true, true); 318 } 319 320 public static PropertyDescriptor[] getBeanGetters(Class type) { 321 return getPropertiesHelper(type, true, false); 322 } 323 324 public static PropertyDescriptor[] getBeanSetters(Class type) { 325 return getPropertiesHelper(type, false, true); 326 } 327 328 private static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) { 329 try { 330 BeanInfo info = Introspector.getBeanInfo(type, Object.class); 331 PropertyDescriptor[] all = info.getPropertyDescriptors(); 332 if (read && write) { 333 return all; 334 } 335 List properties = new ArrayList(all.length); 336 for (int i = 0; i < all.length; i++) { 337 PropertyDescriptor pd = all[i]; 338 if ((read && pd.getReadMethod() != null) || 339 (write && pd.getWriteMethod() != null)) { 340 properties.add(pd); 341 } 342 } 343 return (PropertyDescriptor[])properties.toArray(new PropertyDescriptor[properties.size()]); 344 } catch (IntrospectionException e) { 345 throw new CodeGenerationException(e); 346 } 347 } 348 349 350 351 public static Method findDeclaredMethod(final Class type, 352 final String methodName, final Class[] parameterTypes) 353 throws NoSuchMethodException { 354 355 Class cl = type; 356 while (cl != null) { 357 try { 358 return cl.getDeclaredMethod(methodName, parameterTypes); 359 } catch (NoSuchMethodException e) { 360 cl = cl.getSuperclass(); 361 } 362 } 363 throw new NoSuchMethodException(methodName); 364 365 } 366 367 public static List addAllMethods(final Class type, final List list) { 368 369 370 list.addAll(java.util.Arrays.asList(type.getDeclaredMethods())); 371 Class superclass = type.getSuperclass(); 372 if (superclass != null) { 373 addAllMethods(superclass, list); 374 } 375 Class[] interfaces = type.getInterfaces(); 376 for (int i = 0; i < interfaces.length; i++) { 377 addAllMethods(interfaces[i], list); 378 } 379 380 return list; 381 } 382 383 public static List addAllInterfaces(Class type, List list) { 384 Class superclass = type.getSuperclass(); 385 if (superclass != null) { 386 list.addAll(Arrays.asList(type.getInterfaces())); 387 addAllInterfaces(superclass, list); 388 } 389 return list; 390 } 391 392 393 public static Method findInterfaceMethod(Class iface) { 394 if (!iface.isInterface()) { 395 throw new IllegalArgumentException(iface + " is not an interface"); 396 } 397 Method[] methods = iface.getDeclaredMethods(); 398 if (methods.length != 1) { 399 throw new IllegalArgumentException("expecting exactly 1 method in " + iface); 400 } 401 return methods[0]; 402 } 403 404 public static Class defineClass(String className, byte[] b, ClassLoader loader) throws Exception { 405 Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), PROTECTION_DOMAIN }; 406 return (Class)DEFINE_CLASS.invoke(loader, args); 407 } 408 409 public static int findPackageProtected(Class[] classes) { 410 for (int i = 0; i < classes.length; i++) { 411 if (!Modifier.isPublic(classes[i].getModifiers())) { 412 return i; 413 } 414 } 415 return 0; 416 } 417 }

This page was automatically generated by Maven